home *** CD-ROM | disk | FTP | other *** search
Text File | 1994-05-24 | 10.5 KB | 429 lines | [TEXT/MPS ] |
- This is all of the source code from the article. Much of it
- had text all through it, so it’s not all directly compilable,
- nor does it all read straight through. It’s a bunch of
- snippets and one-liners.
-
-
- if (gHasDragManager) {
- err = InstallTrackingHandler(MyTrackingHandler,
- theWindow, (void *)dataPtr);
- err = InstallReceiveHandler(MyReceiveDropHandler,
- theWindow, (void *)dataPtr);
- }
-
-
-
- if (gHasDragManager) {
- RemoveTrackingHandler(MyTrackingHandler, theWindow);
- RemoveReceiveHandler(MyReceiveDropHandler, theWindow);
- }
-
-
- if (gHasDragManager) {
- tLong = DragItem(theWindow);
- }
- else {
- tLong = DragGrayRgn(gRgn, origClick, &limitRect,
- &slopRect, 0,
- (DragGrayRgnProcPtr)&FileDragHook);
- }
-
-
- long DragItem(WindowPtr theWindow)
- {
- ArcFileType theFile; //program-specific structure
- DragReference theDrag;
- RgnHandle tempRgn;
- Point tPt;
- short result;
- PromiseHFSFlavor hfsFlavor;
- OSErr err;
-
- theFile = GetSelectedFile(theWindow);
-
- //set up to do the drag
- err = NewDrag(&theDrag);
-
- hfsFlavor.fileType = theFile.af_FInfo.fdType;
- hfsFlavor.fileCreator = theFile.af_FInfo.fdCreator;
- hfsFlavor.fdFlags = theFile.af_FInfo.fdFlags;
- hfsFlavor.promisedFlavor = 'VCT1';
- AddDragItemFlavor(theDrag, 1, flavorTypePromiseHFS,
- &hfsFlavor, sizeof(hfsFlavor), flavorNotSaved);
-
- AddDragItemFlavor(theDrag, 1, 'VCT1', nil, 0, 0);
-
- AddDragItemFlavor(theDrag, 1, kDragItem, nil, 0,
- flavorSenderOnly);
-
- SetDragSendProc(theDrag, MySendDataProc, (void *)theWindow);
-
- SetPt(&tPt, 0, 0);
- LocalToGlobal(&tPt);
- OffsetRgn(gRgn, tPt.h, tPt.v);
-
- SetDragItemBounds(theDrag, 1, &(**gRgn).rgnBBox);
-
- tempRgn = NewRgn();
- CopyRgn(gRgn,tempRgn);
- InsetRgn(tempRgn,1,1);
- DiffRgn(gRgn,tempRgn,gRgn);
- DisposeRgn(tempRgn);
-
- // do the drag
- result = TrackDrag(theDrag, &gEvent, gRgn);
-
- //clean up and return the result
- DisposeDrag(theDrag);
-
- if (result) {
- return (0x80008000);
- }
- else {
- return (0);
- }
- }
-
-
- pascal OSErr AddDragItemFlavor(DragReference theDragRef,
- ItemReference theItemRef,
- FlavorType theType,
- void *dataPtr,
- Size dataSize,
- FlavorFlags theFlags);
-
-
- #define flavorTypeHFS 'hfs ' // flavor type for HFS data
- #define flavorTypePromiseHFS 'phfs' // flavor type for promised HFS data
- #define flavorTypeDirectory 'diry' // flavor type for AOCE directories
-
- struct PromiseHFSFlavor {
- OSType fileType; // file type
- OSType fileCreator; // file creator
- unsigned short fdFlags; // Finder flags
- FlavorType promisedFlavor; // promised flavor containing an FSSpec
- };
- typedef struct PromiseHFSFlavor PromiseHFSFlavor;
-
-
- enum {
- flavorSenderOnly = 0x00000001L, // flavor is available to sender only
- flavorSenderTranslated = 0x00000002L, // flavor is translated by sender
- flavorNotSaved = 0x00000004L, // flavor should not be saved
- flavorSystemTranslated = 0x00000100L // flavor is translated by system
- };
-
-
- AddDragItemFlavor(theDrag, 1, 'VCT1', nil, 0, 0);
-
-
- AddDragItemFlavor(theDrag, 1, kDragItem, nil, 0, flavorSenderOnly);
-
-
- SetDragSendProc(theDrag, MySendDataProc, (void *)theWindow);
-
-
- SetPt(&tPt, 0, 0);
- LocalToGlobal(&tPt);
- OffsetRgn(gRgn, tPt.h, tPt.v);
-
-
-
-
- SetDragItemBounds(theDrag, 1, &(**gRgn).rgnBBox);
-
-
- tempRgn = NewRgn();
- CopyRgn(gRgn, tempRgn);
- InsetRgn(tempRgn, 1, 1);
- DiffRgn(gRgn, tempRgn, gRgn);
- DisposeRgn(tempRgn);
-
-
- result = TrackDrag(theDrag, &gEvent, gRgn);
-
-
- err = DisposeDrag(theDrag);
-
-
- pascal OSErr MySendDataProc(FlavorType theFlavor,
- void *refCon,
- ItemReference theItem,
- DragReference theDrag)
- {
- AEDesc dropLoc;
- FSSpec target;
- OSErr err;
- Boolean wasChanged;
-
- if (theFlavor== 'VCT1') {
- err = GetDropLocation(theDrag, &dropLoc);
-
- err = ResolveAlias(nil, (AliasHandle)dropLoc.dataHandle,
- &target, &wasChanged);
- if (err) {
- return (err);
- }
-
- // Decompress item
- err = ExtractSelectedItems((ArchiveWPtr)refCon, &target);
- if (err) {
- return (err);
- }
-
- err = SetDragItemFlavorData(theDrag, theItem, 'VCT1',
- (Ptr)&target, sizeof(target), 0L);
- }
-
- return (noErr);
- }
-
-
-
- pascal OSErr MyTrackingHandler(short message,
- WindowPtr theWindow,
- void *handlerRefCon,
- DragReference theDrag)
-
- { short result;
- unsigned short count;
- unsigned short index;
- unsigned long flavorFlags;
- unsigned long attributes;
- ItemReference theItem;
- RgnHandle theRgn;
- ArchiveWPtr dataPtr = (ArchiveWPtr)handlerRefCon;
- ArchiveWPtr hitDataPtr;
- Point theMouse;
- Point localMouse;
- Rect tRect;
-
- //
- // We decide whether we can accept the data when we are called with
- // a message of dragTrackingEnterHandler. If we can, we set gCanAcceptItems
- // to true.
- //
-
- if ((message != dragTrackingEnterHandler)
- && (!gCanAcceptItems)) {
- return (noErr);
- }
-
- GetDragAttributes(theDrag, &attributes);
-
- switch (message) {
- case dragTrackingEnterHandler:
- //
- // by default our window can always accept items
- //
- gCanAcceptItems = true;
-
- //
- // find out how many items have being dragged
- //
- CountDragItems(theDrag, &count);
-
- for (index = 1; index <= count; index++) {
- //
- // get the item reference number for the nth item being dragged
- //
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- //
- // See if a flavor of flavorTypeHFS exists for this drag item
- // If one does exist, then we can accept this item, so continue
- // checking the rest of the items.
- // An item being dragged from the Finder to our window would qualify
- // as this type.
- //
- result = GetFlavorFlags(theDrag, theItem,
- flavorTypeHFS, &flavorFlags);
-
- if (result == noErr) {
- continue;
- }
-
- //
- // See if a flavor of kDragItem (our proprietary flavor) exists.
- // If it does and the drag flags indicate we started the drag then
- // we are simply moving the file in the file list, so we can accept
- // this type.
- //
- result = GetFlavorFlags(theDrag, theItem,
- kDragItem, &flavorFlags);
-
- if ((result == noErr)
- && (flavorFlags & flavorSenderOnly)) {
- continue;
- }
-
- //
- // We couldn’t find and flavors that we wanted so we will not
- // accept the data.
- //
- gCanAcceptItems = false;
- break;
- }
-
- break;
-
- case dragTrackingEnterWindow:
- gCursorInContent = false;
- break;
-
- case dragTrackingInWindow:
- //
- // The user is dragging items over our window.
- // We need to determine if we’ve left our window because the Human
- // Interface Guidelines state that no hiliting is to be done until
- // the user drags outside of the sender window.
- //
- GetDragMouse(theDrag, &theMouse, 0L);
- localMouse = theMouse;
- GlobalToLocal(&localMouse);
-
- if (attributes & dragHasLeftSenderWindow) {
- //
- // The user has dragged outside of the sender window so we are now
- // free to perform hiliting to indicate whether or not the drag
- // can be accepted by the window.
- // We check to see if the user is dragging into our window, and
- // if so, have we shown the drag hilite? If it is appropriate we
- // will show the drag hilite, meaning the user can drop the drag
- // items here.
- // If the user is not dragging in our window, we check to see if
- // the drag hilite is shown. If it is we hide the drag hilite.
- //
- tRect = (**(dataPtr->ArcList)).rView;
- InsetRect(&tRect, 2, 1);
-
- if (PtInRect(localMouse, &tRect)) {
- if (!gCursorInContent) {
- InsetRect(&tRect, -2, -4);
- tRgn = NewRgn();
- RectRgn(theRgn, &tRect);
- ShowDragHilite(theDrag, theRgn, true);
- DisposeRgn(theRgn);
- }
-
- gCursorInContent = true;
-
- }
- else {
- if (gCursorInContent) {
- HideDragHilite(theDrag);
- gCursorInContent = false;
- }
- }
- }
-
- //
- // This is our own routine which will return a pointer to a data
- // structure we maintain for each window.
- // We check to see if we are dragging in the sender window. If we
- // are, we call one of our routines to handle hiliting of items in
- // the window, autoscrolling, and other various operations.
- //
- FindDataPtrGivenMousePt(theMouse, &hitDataPtr);
-
- if (hitDataPtr == dataPtr) {
- HandleSameWindowDrag(theWindow);
- }
-
- break;
-
- case dragTrackingLeaveWindow:
- //
- // Remove window highlighting, if showing.
- //
- if ((gCursorInContent)
- && (attributes & dragHasLeftSenderWindow)) {
- HideDragHilite(theDrag);
- }
-
- break;
-
- case dragTrackingLeaveHandler:
- break;
- }
-
- return (noErr);
- }
-
-
- pascal OSErr MyReceiveDropHandler(WindowPtr theWindow, void *handlerRefCon, DragReference theDrag)
- {
- unsigned short items;
- short index;
- ItemReference theItem;
- FlavorFlags theFlags;
- Size dataSize;
- HFSFlavor theHFS;
- OSErr result;
-
- //
- // find out how many items where dragged
- //
- CountDragItems(theDrag, &items);
-
- for (index = 1; index <= items; index++) {
- //
- // Get the item reference number for this drag item so we can find out
- // additional information later on.
- //
- GetDragItemReferenceNumber(theDrag, index, &theItem);
-
- //
- // Get the flavor flags for this object’s flavor of kDragItem.
- // If we can find flags for this flavor, then we know that the drag
- // was completed in the sender window, so what the user did was simply
- // move an item in our file list.
- //
- result = GetFlavorFlags( theDrag, theItem, kDragItem,
- &theFlags);
- if ((result == noErr) && (flavorFlags & flavorSenderOnly)) {
- //
- // Move the item that the user dragged to the new location in the file list
- //
- MoveListItem(theWindow,
- ((ArchiveWPtr)theWindow)->ArcnIndexes, gLastLine);
- }
- else {
- // it wasn’t a drag from one of our windows, so let’s see if a
- // file system object was dragged to our window.
- //
- // Get the flavor flags for this object’s flavor of flavorTypeHFS
- //
- result = GetFlavorFlags( theDrag, theItem,
- flavorTypeHFS, &theFlags);
-
- if (result == noErr) {
- //
- // If we are here then the object contained a flavorTypeHFS so we
- // need to know how much data it contains (we really do know how
- // much data is has, but it doesn’t hurt to make this call.
- //
- GetFlavorDataSize(theDrag, theItem, flavorTypeHFS,
- &dataSize);
-
- //
- // Get the actual flavor data
- //
- GetFlavorData( theDrag, theItem, flavorTypeHFS,
- &theHFS, &dataSize, 0L);
-
- //
- // Make sure the window does not have it’s drag hilite showing
- //
- HideDragHilite(theDrag);
-
- //
- // Add the dragged files to our archive
- //
- AddFilesToArchive(theWindow, &theHFS);
- }
- }
-
- return (noErr);
- }
-